[][src]Crate bbqueue

BBQueue

BBQueue, short for "BipBuffer Queue", is a (work in progress) Single Producer Single Consumer, lockless, no_std, thread safe, queue, based on BipBuffers.

It is designed (primarily) to be a First-In, First-Out queue for use with DMA on embedded systems.

While Circular/Ring Buffers allow you to send data between two threads (or from an interrupt to main code), you must push the data one piece at a time. With BBQueue, you instead are granted a block of contiguous memory, which can be filled (or emptied) by a DMA engine.

Using in a single threaded context

use bbqueue::{BBQueue, bbq};

fn main() {
    // Create a statically allocated instance
    let bbq = bbq!(1024).unwrap();

    // Obtain a write grant of size 128 bytes
    let mut wgr = bbq.grant(128).unwrap();

    // Fill the buffer with data
    wgr.copy_from_slice(&[0xAFu8; 128]);

    // Commit the write, to make the data available to be read
    bbq.commit(wgr.len(), wgr);

    // Obtain a read grant of all available and contiguous bytes
    let rgr = bbq.read().unwrap();

    for i in 0..128 {
        assert_eq!(rgr[i], 0xAFu8);
    }

    // Release the bytes, allowing the space
    // to be re-used for writing
    bbq.release(rgr.len(), rgr);
}

Using in a multi-threaded environment (or with interrupts, etc.)

use bbqueue::{BBQueue, bbq};
use std::thread::spawn;

fn main() {
    // Create a statically allocated instance
    let bbq = bbq!(1024).unwrap();
    let (mut tx, mut rx) = bbq.split();

    let txt = spawn(move || {
        for tx_i in 0..128 {
            'inner: loop {
                match tx.grant(4) {
                    Ok(mut gr) => {
                        gr.copy_from_slice(&[tx_i as u8; 4]);
                        tx.commit(4, gr);
                        break 'inner;
                    }
                    _ => {}
                }
            }
        }
    });

    let rxt = spawn(move || {
        for rx_i in 0..128 {
            'inner: loop {
                match rx.read() {
                    Ok(mut gr) => {
                        if gr.len() < 4 {
                            rx.release(0, gr);
                            continue 'inner;
                        }

                        assert_eq!(&gr[..4], &[rx_i as u8; 4]);
                        rx.release(4, gr);
                        break 'inner;
                    }
                    _ => {}
                }
            }
        }
    });

    txt.join().unwrap();
    rxt.join().unwrap();
}

Macros

bbq

Statically allocate a BBQueue singleton object with a given size (in bytes).

cortex_m_bbq

Like the bbq!() macro, but wraps the initialization in a cortex-m "critical section" by disabling interrupts

unchecked_bbq

This macro does try to provide similar guarantees as bbq!(), but is not thread safe.

Structs

BBQueue

A single producer, single consumer, thread safe queue

Consumer

An opaque structure, capable of reading data from the queue

GrantR

A structure representing a contiguous region of memory that may be read from, and potentially "released" (or cleared) from the queue

GrantW

A structure representing a contiguous region of memory that may be written to, and potentially "committed" to the queue

Producer

An opaque structure, capable of writing data to the queue

Enums

Error

Error type used by the BBQueue interfaces

Type Definitions

Result

Result type used by the BBQueue interfaces